package v1

import (
	"RoccBlog/global"
	. "RoccBlog/model"
	"RoccBlog/model/req_resp"
	"RoccBlog/repository/v1"
	"RoccBlog/service"
	"RoccBlog/util"
	"RoccBlog/util/constant"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"log"
	"time"
)

type UserService struct {
	service.BaseService
	service.BaseOperationService
	Repository v1.UserRepository
}

func init() {
	global.RegisterService(&UserService{
		Repository: v1.UserRepository{},
	})
}

func (s *UserService) Add(ctx *gin.Context, data req_resp.LoginUserReq) error {
	password, err := util.BcryptPassword(data.Password)
	if err != nil {
		return err
	}
	data.Password = password
	var user User
	copier.Copy(&user, &data)
	return s.Repository.Create(user)
}

func (s *UserService) Register(ctx *gin.Context, data req_resp.RegisterUserReq) error {

	//判断验证码是否匹配
	verifyCode, _ := global.RedisClient.Get(ctx, data.Email).Result()
	if data.VerifyCode != verifyCode {
		return errors.New("邮箱验证码错误")
	}

	password, err := util.BcryptPassword(data.Password)
	if err != nil {
		return err
	}
	data.Password = password
	var user User
	copier.Copy(&user, &data)
	//将用户设置为正常
	user.State = 1
	return s.Repository.Create(user)
}

func (s *UserService) Remove(ctx *gin.Context, id int) error {
	return s.Repository.Delete(id)
}

func (s *UserService) Modify(ctx *gin.Context, data req_resp.ModifyUserReq) error {
	var user User
	copier.Copy(&user, &data)
	return s.Repository.Update(user)
}

func (s *UserService) FindById(ctx *gin.Context, id int) (User, error) {
	return s.Repository.SelectById(id)
}

func (s *UserService) Find(ctx *gin.Context, data req_resp.UserQueryReq) (any, error) {
	size, num := s.GetPage(ctx)
	return s.Repository.Select(data, num, size)
}

func (s *UserService) FindByName(ctx *gin.Context, username string) (User, error) {
	return s.Repository.SelectByName(username)
}

func (s *UserService) LoginUser(ctx *gin.Context, user req_resp.LoginUserReq) (*req_resp.LoginUserResp, string, error) {

	//查找用户
	dbUser, err := s.FindByName(ctx, user.Username)
	if err != nil {
		return nil, "", err
	}

	//对比密码是否正确
	err = util.ComparePassword(dbUser.Password, user.Password)
	if err != nil {
		return nil, "", err
	}

	jsonStr, err := json.Marshal(dbUser)
	if err != nil {
		return nil, "", err
	}
	token, err := util.GeneratorToken(fmt.Sprint(dbUser.Id))
	if err != nil {
		return nil, "", err
	}
	// 将登录信息存储到redis中
	key := constant.RedisLoginUserPrefix + fmt.Sprint(dbUser.Id) + token
	log.Println("redis 存储key=", key)
	global.RedisClient.Set(ctx, key, jsonStr, time.Minute*time.Duration(global.Config.Jwt.Expire))

	var resp = req_resp.LoginUserResp{
		Id:        dbUser.Id,
		NickName:  dbUser.NickName,
		AvatarUrl: dbUser.AvatarUrl,
		LastTime:  dbUser.LastTime,
		Roles:     dbUser.Roles,
	}

	//登录成功修改最后登录时间
	localTime := LocalTime(time.Now())
	dbUser.LastTime = &localTime
	s.Repository.Update(dbUser)

	return &resp, token, nil
}

// Logout 退出登录
func (s *UserService) Logout(ctx *gin.Context) error {

	//获取登录用户
	user, err := s.GetLoginUser(ctx)
	if err != nil {
		return err
	}

	//删除redis Key
	return global.RedisClient.Del(ctx, constant.RedisLoginUserPrefix+fmt.Sprint(user.Id)+ctx.GetHeader(constant.TokenHeaderName)).Err()
}

// ResetPassword 重置密码
func (s *UserService) ResetPassword(ctx *gin.Context, id int) error {
	password, err := util.BcryptPassword("12345678")
	if err != nil {
		return err
	}
	return s.Repository.ResetPassword(id, password)
}
